const { Attendance, Student, Class, User } = require('../models/db');

const ok = (res, data, extra = {}) => res.json({ success: true, data, ...extra });
const fail = (res, code = 500, message = '服务器错误') => res.status(code).json({ success: false, message, code });

const mapAttendanceToClient = (a) => ({
  id: a._id?.toString(),
  serialNumber: a.serialNumber,
  attendanceDate: a.attendanceDate ? new Date(a.attendanceDate).toISOString().split('T')[0] : undefined,
  studentId: a.student ? a.student._id?.toString() || a.student?.toString() : undefined,
  studentName: a.studentName || a.student?.name,
  classId: a.class ? a.class._id?.toString() || a.class?.toString() : undefined,
  className: a.className || a.class?.className,
  academy: a.academy || a.student?.academy,
  status: a.status,
  remark: a.remark,
  reviewerId: a.reviewer ? a.reviewer._id?.toString() || a.reviewer?.toString() : undefined,
  reviewerName: a.reviewerName || a.reviewer?.username,
  createdAt: a.createdAt ? new Date(a.createdAt).toISOString() : undefined,
});

const mapClientToAttendance = (body) => ({
  attendanceDate: body.attendanceDate ? new Date(body.attendanceDate) : new Date(),
  student: body.studentId,
  studentName: body.studentName,
  class: body.classId,
  className: body.className,
  academy: body.academy,
  status: body.status,
  remark: body.remark,
  reviewer: body.reviewerId,
  reviewerName: body.reviewerName,
});

// 获取序号（递增）
const getNextSerialNumber = async () => {
  const lastRecord = await Attendance.findOne().sort({ serialNumber: -1 });
  if (!lastRecord || !lastRecord.serialNumber) {
    // 如果没有记录，统计总数+1
    const count = await Attendance.countDocuments();
    return count + 1;
  }
  return lastRecord.serialNumber + 1;
};

exports.getAllAttendances = async (req, res) => {
  try {
    const { page = 1, limit = 20, studentId, classId, status, startDate, endDate } = req.query;
    const skip = (parseInt(page) - 1) * parseInt(limit);
    const query = {};
    
    if (studentId) query.student = studentId;
    if (classId) query.class = classId;
    if (status) query.status = status;
    if (startDate || endDate) {
      query.attendanceDate = {};
      if (startDate) query.attendanceDate.$gte = new Date(startDate);
      if (endDate) query.attendanceDate.$lte = new Date(endDate);
    }
    
    const attendances = await Attendance.find(query)
      .populate('student', 'studentId name academy')
      .populate('class', 'className academy')
      .populate('reviewer', 'username')
      .sort({ attendanceDate: -1, createdAt: -1 })
      .skip(skip)
      .limit(parseInt(limit));
    
    const total = await Attendance.countDocuments(query);
    ok(res, attendances.map(mapAttendanceToClient), {
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        totalPages: Math.ceil(total / parseInt(limit))
      }
    });
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.getAttendanceById = async (req, res) => {
  try {
    const a = await Attendance.findById(req.params.id)
      .populate('student', 'studentId name academy')
      .populate('class', 'className academy')
      .populate('reviewer', 'username');
    if (!a) return fail(res, 404, '未找到该考勤记录');
    ok(res, mapAttendanceToClient(a));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.createAttendance = async (req, res) => {
  try {
    const payload = mapClientToAttendance(req.body || {});
    if (!payload.student || !payload.class || !payload.status) {
      return fail(res, 400, '缺少必要字段: studentId | classId | status');
    }
    
    // 填充冗余字段
    const student = await Student.findById(payload.student);
    const classInfo = await Class.findById(payload.class);
    if (!student || !classInfo) {
      return fail(res, 400, '学生或班级不存在');
    }
    
    payload.studentName = student.name;
    payload.className = classInfo.className;
    payload.academy = student.academy || classInfo.academy;
    payload.serialNumber = await getNextSerialNumber();
    
    const created = await Attendance.create(payload);
    const a = await Attendance.findById(created._id)
      .populate('student', 'studentId name')
      .populate('class', 'className')
      .populate('reviewer', 'username');
    ok(res, mapAttendanceToClient(a));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.updateAttendance = async (req, res) => {
  try {
    const payload = mapClientToAttendance(req.body || {});
    
    // 如果更新了学生或班级，需要重新填充冗余字段
    if (payload.student || payload.class) {
      if (payload.student) {
        const student = await Student.findById(payload.student);
        if (student) {
          payload.studentName = student.name;
          payload.academy = student.academy;
        }
      }
      if (payload.class) {
        const classInfo = await Class.findById(payload.class);
        if (classInfo) {
          payload.className = classInfo.className;
          if (!payload.academy) payload.academy = classInfo.academy;
        }
      }
    }
    
    const updated = await Attendance.findByIdAndUpdate(req.params.id, payload, { new: true })
      .populate('student', 'studentId name')
      .populate('class', 'className')
      .populate('reviewer', 'username');
    if (!updated) return fail(res, 404, '未找到该考勤记录');
    ok(res, mapAttendanceToClient(updated));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.deleteAttendance = async (req, res) => {
  try {
    const deleted = await Attendance.findByIdAndDelete(req.params.id);
    if (!deleted) return fail(res, 404, '未找到该考勤记录');
    ok(res, { id: req.params.id });
  } catch (e) {
    fail(res, 500, e.message);
  }
};

